package com.suke.czx.modules.incentive.service.impl;

import cn.hutool.core.util.StrUtil;
import com.suke.czx.common.utils.*;
import com.suke.czx.modules.incentive.entity.*;
import com.suke.czx.modules.incentive.mapper.IncentiveMapper;
import com.suke.czx.modules.incentive.service.IncentiveService;
import com.suke.czx.modules.performanceconfig.entity.*;
import com.suke.czx.modules.performanceconfig.strategy.PerformanceCalculateStrategy;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 应用模块名称: 绩效
 * 代码描述: 绩效业务层
 * copyright: AUZAR ALL RIGHTS RESERVED
 * company: AUZAR
 *
 * @author: 颜米晨
 * @date: 2022/07/27 19:48
 */
@Slf4j
@Service
@AllArgsConstructor
public class IncentiveServiceImpl implements IncentiveService {

    private final IncentiveMapper incentiveMapper;

    /**
     * 校验绩效参数是否完整
     * @param year 年份
     * @param version 版本
     * @return VO
     */
    public R configVerify(String year, Integer version) {
        Set<Integer> configSet = incentiveMapper.configVerify(year, version);
        if (SetUtil.size(configSet) == 9) {
            return R.ok();
        } else {
            StringBuilder builder = new StringBuilder("年份:" + year + ",版本:" + version + ",缺失绩效参数组别:");
            List<String> job2NameList = Arrays.asList("专职业务员", "兼职业务员", "项目经理", "策划组", "UI设计&动效创意组", "程序组", "内容组", "硬件开发组", "行政");
            Arrays.asList(CodeConstant.PRO_BUSINESS, CodeConstant.PART_BUSINESS, CodeConstant.PROJECT_MANAGER, CodeConstant.PRODUCTION_PLAN, CodeConstant.PRODUCTION_UI,
                    CodeConstant.PRODUCTION_PROGRAM, CodeConstant.PRODUCTION_CONTENT, CodeConstant.PRODUCTION_HARDWARE, CodeConstant.ADMINISTRATION)
                    .forEach(c -> builder.append(configSet.contains(c) ? CommonConstant.BLANK : job2NameList.get(c - 1) + CommonConstant.COMMA));
            return R.error(StrUtil.sub(StrUtil.toString(builder), 0, StrUtil.length(StrUtil.toString(builder)) - 1));
        }
    }

    /**
     * 查询已关联绩效参数年份版本
     * @param projectId 项目id
     * @return VO
     */
    @Override
    public R related(Long projectId) {
        return R.ok().setData(incentiveMapper.related(projectId));
    }

    /**
     * 查询绩效考核参数
     * @param incentiveGenerateBo 绩效考核参数查询BO
     * @return VO
     */
    @Override
    public R search(IncentiveGenerateBo incentiveGenerateBo) {
        Map<Integer, IncentiveEvaluation> evaluationMap = incentiveMapper.getIncentiveEvaluation(incentiveGenerateBo);
        return R.ok().setData(evaluationMap);
    }

    /**
     * 绩效考核
     * @param incentiveGenerateBo 绩效考核参数BO
     * @param userId 用户id
     * @return VO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R evaluate(IncentiveGenerateBo incentiveGenerateBo, Long userId) {
        // 根据绩效年份及版本查询所有绩效参数
        Map<Integer, PerformanceConfig> performanceConfigMap = incentiveMapper.getPerformanceConfigByYearAndVersion(
                incentiveGenerateBo.getYear(), incentiveGenerateBo.getVersion());
        if (MapUtil.size(performanceConfigMap) < 9) {
            return R.error("所选年份版本绩效参数不完整,请先完善绩效参数再生成绩效");
        }
        // 查询是否在该合同,该年份,该版本,该组别下是否已考核绩效
        List<Long> performanceConfigIdList = incentiveMapper.getEvaluationCount(incentiveGenerateBo.getProjectId(), incentiveGenerateBo.getYear(),
                incentiveGenerateBo.getVersion(), incentiveGenerateBo.getJob2());
        IncentiveEvaluation incentiveEvaluation = new IncentiveEvaluation();
        incentiveEvaluation.setProjectId(incentiveGenerateBo.getProjectId());
        incentiveEvaluation.setJob2(incentiveGenerateBo.getJob2());
        incentiveEvaluation.setPerformanceConfigId(performanceConfigMap.get(incentiveGenerateBo.getJob2()).getPerformanceConfigId());
        incentiveEvaluation.setEvaluation1(incentiveGenerateBo.getEvaluation1());
        incentiveEvaluation.setEvaluation2(incentiveGenerateBo.getEvaluation2());
        incentiveEvaluation.setEvaluation3(incentiveGenerateBo.getEvaluation3());
        incentiveEvaluation.setEvaluation4(incentiveGenerateBo.getEvaluation4());
        if (ListUtil.isEmpty(performanceConfigIdList)) {
            // 没有绩效考核记录,执行新增操作
            incentiveEvaluation.setGenerateTime(new Date());
            incentiveEvaluation.setCreator(userId);
            incentiveEvaluation.setCreateTime(new Date());
            incentiveMapper.insertIncentiveEvaluation(incentiveEvaluation);
            log.info("新增绩效考核,项目id:{},组别:{},绩效参数id:{},考核参数1:{},考核参数2:{},考核参数3:{},考核参数4:{}", incentiveEvaluation.getProjectId(),
                    incentiveEvaluation.getJob2(), incentiveEvaluation.getPerformanceConfigId(), incentiveEvaluation.getEvaluation1(),
                    incentiveEvaluation.getEvaluation2(), incentiveEvaluation.getEvaluation3(), incentiveEvaluation.getEvaluation4());
        } else {
            // 否则执行更新操作
            incentiveEvaluation.setUpdater(userId);
            incentiveEvaluation.setUpdateTime(new Date());
            incentiveMapper.updateIncentiveEvaluation(incentiveEvaluation);
            log.info("更新绩效考核,项目id:{},组别:{},绩效参数id:{},考核参数1:{},考核参数2:{},考核参数3:{},考核参数4:{}", incentiveEvaluation.getProjectId(),
                    incentiveEvaluation.getJob2(), incentiveEvaluation.getPerformanceConfigId(), incentiveEvaluation.getEvaluation1(),
                    incentiveEvaluation.getEvaluation2(), incentiveEvaluation.getEvaluation3(), incentiveEvaluation.getEvaluation4());
        }
        return R.ok();
    }

    /**
     * 绩效分配
     * @param incentiveAllocation 绩效分配实体
     * @param userId 用户id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R allocate(IncentiveAllocation incentiveAllocation, Long userId) {
        // 查询是否员工在该项目,该组别,该绩效参数下是否已分配绩效
        if (incentiveMapper.getAllocationCount(incentiveAllocation.getProjectId(), incentiveAllocation.getJob2(),
                incentiveAllocation.getPerformanceConfigId(), incentiveAllocation.getUserId()) == 0) {
            // 没有绩效分配记录,执行新增操作
            incentiveAllocation.setGenerateTime(new Date());
            incentiveAllocation.setCreator(userId);
            incentiveAllocation.setCreateTime(new Date());
            incentiveMapper.insertIncentiveAllocation(incentiveAllocation);
            log.info("新增绩效分配,项目id:{},组别:{},绩效参数id:{},员工id:{},分配比例:{}", incentiveAllocation.getProjectId(),
                    incentiveAllocation.getJob2(), incentiveAllocation.getPerformanceConfigId(), incentiveAllocation.getUserId(),
                    incentiveAllocation.getRate());
        } else {
            // 否则执行更新操作
            incentiveAllocation.setUpdater(userId);
            incentiveAllocation.setUpdateTime(new Date());
            incentiveMapper.updateIncentiveAllocation(incentiveAllocation);
            log.info("更新绩效分配,项目id:{},组别:{},绩效参数id:{},员工id:{},分配比例:{}", incentiveAllocation.getProjectId(),
                    incentiveAllocation.getJob2(), incentiveAllocation.getPerformanceConfigId(), incentiveAllocation.getUserId(),
                    incentiveAllocation.getRate());
        }
        return R.ok();
    }

    /**
     * 删除绩效分配
     * @param incentiveId 绩效分配id
     * @param userId 用户id
     * @return VO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R delAllocate(Long incentiveId, Long userId) {
        incentiveMapper.deleteIncentiveAllocation(incentiveId, userId);
        return R.ok();
    }

    /**
     * 绩效生成
     * @param incentiveGenerateBo 绩效生成BO
     * @param userId 用户id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R generate(IncentiveGenerateBo incentiveGenerateBo, Long userId) {
        // 1.动态生成绩效
        R r = dynamicGenerateIncentive(incentiveGenerateBo);
        // 2.如果生成成功新增生产版本记录
        if (r.get(FieldConstant.CODE) != null && NumUtil.null2IntegerZero(StrUtil.toString(r.get(FieldConstant.CODE))) == 0) {
            insertIncentiveVersion(incentiveGenerateBo, userId);
        }
        return r;
    }

    /**
     * 初始化绩效
     * @param incentiveGenerateBo 绩效生成BO
     * @return VO
     */
    @Override
    public R initial(IncentiveGenerateBo incentiveGenerateBo) {
        if (StrUtil.isNotBlank(incentiveGenerateBo.getYear()) && incentiveGenerateBo.getVersion() != null) {
            // 如果初始化切换年份和版本直接展示该年份版本绩效
            R r = dynamicGenerateIncentive(incentiveGenerateBo);
            if (r.get(FieldConstant.CODE) != null && NumUtil.null2IntegerZero(StrUtil.toString(r.get(FieldConstant.CODE))) == 0) {
                return Objects.requireNonNull(r.put(FieldConstant.YEAR, incentiveGenerateBo.getYear())).put(FieldConstant.VERSION, incentiveGenerateBo.getVersion());
            }
        } else {
            // 如果未传入年份和版本
            // 查询是否已有发放记录,如果有发放记录直接展示已有发放记录的版本
            List<Map<String, Object>> dataList = incentiveMapper.grantRecord(incentiveGenerateBo.getProjectId());
            if (ListUtil.isEmpty(dataList)) {
                // 否则取最新关联版本展示
                dataList = incentiveMapper.versionRecord(incentiveGenerateBo.getProjectId());
            }
            if (!ListUtil.isEmpty(dataList)) {
                incentiveGenerateBo.setYear(StrUtil.toString(dataList.get(0).get(FieldConstant.YEAR)));
                incentiveGenerateBo.setVersion(NumUtil.null2IntegerZero(StrUtil.toString(dataList.get(0).get(FieldConstant.VERSION))));
                R r = dynamicGenerateIncentive(incentiveGenerateBo);
                if (r.get(FieldConstant.CODE) != null && NumUtil.null2IntegerZero(StrUtil.toString(r.get(FieldConstant.CODE))) == 0) {
                    return Objects.requireNonNull(r.put(FieldConstant.YEAR, incentiveGenerateBo.getYear())).put(FieldConstant.VERSION, incentiveGenerateBo.getVersion());
                } else {
                    return r;
                }
            }
        }
        return R.ok();
    }

    /**
     * 动态生成绩效
     * @param incentiveGenerateBo 绩效生成BO
     * @return R VO
     */
    private R dynamicGenerateIncentive(IncentiveGenerateBo incentiveGenerateBo) {
        // 1.根据绩效年份及版本查询所有绩效参数
        Map<Integer, PerformanceConfig> performanceConfigMap = incentiveMapper.getPerformanceConfigByYearAndVersion(
                incentiveGenerateBo.getYear(), incentiveGenerateBo.getVersion());
        if (MapUtil.size(performanceConfigMap) < 9) {
            return R.error("所选年份版本绩效参数不完整,请先完善绩效参数再生成绩效");
        }
        // 2.查询项目金额,工程固定提成硬件金额,工程固定提成软件金额,生产软件金额,生产硬件金额
        GenerateMoney generateMoney = incentiveMapper.getGenerateMoney(incentiveGenerateBo.getProjectId());
        if (generateMoney == null || NumUtil.null2Zero(generateMoney.getSalesMoney()).compareTo(BigDecimal.ZERO) == 0) {
            return R.error("销售金额不存在或等于0不能生成绩效");
        }
        // 3.计算项目毛利率:毛利额 = (销售合同额 * (1-去年运营成本率) - 采购合同额),毛利率 = 毛利额/销售合同额
        BigDecimal grossRate = CalculateUtil.divide(
                CalculateUtil.subtract(
                        CalculateUtil.multiply(
                                generateMoney.getSalesMoney(),
                                CalculateUtil.subtract(BigDecimal.ONE, performanceConfigMap.get(CodeConstant.PRO_BUSINESS).getMarginRemovalRate(), 4)),
                        generateMoney.getCostMoney()),
                generateMoney.getSalesMoney(), 4);
        // 4.查询绩效考核参数
        Map<Integer, IncentiveEvaluation> incentiveEvaluationMap = incentiveMapper.getIncentiveEvaluation(incentiveGenerateBo);
        // 5.生成绩效
        // 5.1.专职业务员绩效
        BusinessPerformance proBusinessPerformance = PerformanceCalculateStrategy.calculateBusinessPerformance(
                new SimulationParam(generateMoney.getSalesMoney(), null, null,
                        grossRate, null, null, null, null),
                performanceConfigMap.get(CodeConstant.PRO_BUSINESS));
        Incentive proBusiness = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PRO_BUSINESS,
                performanceConfigMap.get(CodeConstant.PRO_BUSINESS).getPerformanceConfigId(), proBusinessPerformance.getGrossReward(),
                proBusinessPerformance.getFixReward());
        // 5.2.兼职业务员绩效
        BusinessPerformance partBusinessPerformance = PerformanceCalculateStrategy.calculateBusinessPerformance(
                new SimulationParam(generateMoney.getSalesMoney(), null, null,
                        grossRate, null, null, null, null),
                performanceConfigMap.get(CodeConstant.PART_BUSINESS));
        Incentive partBusiness = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PART_BUSINESS,
                performanceConfigMap.get(CodeConstant.PART_BUSINESS).getPerformanceConfigId(), partBusinessPerformance.getGrossReward(),
                CalculateUtil.add(partBusinessPerformance.getFixReward(), partBusinessPerformance.getInfoReward(), 4));
        // 5.3.项目经理绩效
        ProjectPerformance projectPerformance = PerformanceCalculateStrategy.calculateProjectPerformance(
                new SimulationParam(generateMoney.getSalesMoney(), generateMoney.getProjectHardwareMoney(), generateMoney.getProjectSoftwareMoney(), grossRate,
                        incentiveEvaluationMap.containsKey(CodeConstant.PROJECT_MANAGER) ? incentiveEvaluationMap.get(CodeConstant.PROJECT_MANAGER).getEvaluation1() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PROJECT_MANAGER) ? incentiveEvaluationMap.get(CodeConstant.PROJECT_MANAGER).getEvaluation2() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PROJECT_MANAGER) ? incentiveEvaluationMap.get(CodeConstant.PROJECT_MANAGER).getEvaluation3() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PROJECT_MANAGER) ? incentiveEvaluationMap.get(CodeConstant.PROJECT_MANAGER).getEvaluation4() : null),
                performanceConfigMap.get(CodeConstant.PROJECT_MANAGER));
        Incentive projectManager = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PROJECT_MANAGER,
                performanceConfigMap.get(CodeConstant.PROJECT_MANAGER).getPerformanceConfigId(), projectPerformance.getProjectManagerGrossReward(),
                CalculateUtil.add(projectPerformance.getHardwareReward(), projectPerformance.getSoftwareReward(), 4));
        // 5.4.项目组绩效
        Incentive projectTeam = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PROJECT_TEAM,
                performanceConfigMap.get(CodeConstant.PROJECT_MANAGER).getPerformanceConfigId(), projectPerformance.getProjectGrossReward(),
                projectPerformance.getProjectFixReward());
        // 5.5.策划组绩效
        ProductionPerformance chProductionPerformance = PerformanceCalculateStrategy.calculateProductionPerformance(
                new SimulationParam(generateMoney.getProductionSoftwareMoney(), null, null, null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_PLAN) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_PLAN).getEvaluation1() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_PLAN) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_PLAN).getEvaluation2() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_PLAN) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_PLAN).getEvaluation3() : null, null),
                performanceConfigMap.get(CodeConstant.PRODUCTION_PLAN));
        Incentive ch = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PRODUCTION_PLAN,
                performanceConfigMap.get(CodeConstant.PRODUCTION_PLAN).getPerformanceConfigId(), chProductionPerformance.getReward(), null);
        // 5.6.UI设计&动效创意组绩效
        ProductionPerformance uiProductionPerformance = PerformanceCalculateStrategy.calculateProductionPerformance(
                new SimulationParam(generateMoney.getProductionSoftwareMoney(), null, null, null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_UI) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_UI).getEvaluation1() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_UI) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_UI).getEvaluation2() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_UI) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_UI).getEvaluation3() : null, null),
                performanceConfigMap.get(CodeConstant.PRODUCTION_UI));
        Incentive ui = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PRODUCTION_UI,
                performanceConfigMap.get(CodeConstant.PRODUCTION_UI).getPerformanceConfigId(), uiProductionPerformance.getReward(), null);
        // 5.7.程序组绩效
        ProductionPerformance cxProductionPerformance = PerformanceCalculateStrategy.calculateProductionPerformance(
                new SimulationParam(generateMoney.getProductionSoftwareMoney(), null, null, null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_PROGRAM) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_PROGRAM).getEvaluation1() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_PROGRAM) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_PROGRAM).getEvaluation2() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_PROGRAM) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_PROGRAM).getEvaluation3() : null, null),
                performanceConfigMap.get(CodeConstant.PRODUCTION_PROGRAM));
        Incentive cx = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PRODUCTION_PROGRAM,
                performanceConfigMap.get(CodeConstant.PRODUCTION_PROGRAM).getPerformanceConfigId(), cxProductionPerformance.getReward(), null);
        // 5.8.内容组绩效
        ProductionPerformance nrProductionPerformance = PerformanceCalculateStrategy.calculateProductionPerformance(
                new SimulationParam(generateMoney.getProductionSoftwareMoney(), null, null, null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_CONTENT) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_CONTENT).getEvaluation1() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_CONTENT) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_CONTENT).getEvaluation2() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_CONTENT) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_CONTENT).getEvaluation3() : null, null),
                performanceConfigMap.get(CodeConstant.PRODUCTION_CONTENT));
        Incentive nr = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PRODUCTION_CONTENT,
                performanceConfigMap.get(CodeConstant.PRODUCTION_CONTENT).getPerformanceConfigId(), nrProductionPerformance.getReward(), null);
        // 5.9.硬件开发组绩效
        ProductionPerformance yjProductionPerformance = PerformanceCalculateStrategy.calculateProductionPerformance(
                new SimulationParam(generateMoney.getProductionHardwareMoney(), null, null, null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_HARDWARE) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_HARDWARE).getEvaluation1() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_HARDWARE) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_HARDWARE).getEvaluation2() : null,
                        incentiveEvaluationMap.containsKey(CodeConstant.PRODUCTION_HARDWARE) ? incentiveEvaluationMap.get(CodeConstant.PRODUCTION_HARDWARE).getEvaluation3() : null, null),
                performanceConfigMap.get(CodeConstant.PRODUCTION_HARDWARE));
        Incentive yj = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.PRODUCTION_HARDWARE,
                performanceConfigMap.get(CodeConstant.PRODUCTION_HARDWARE).getPerformanceConfigId(), yjProductionPerformance.getReward(), null);
        // 5.10.行政绩效
        ManagementPerformance managementPerformance = PerformanceCalculateStrategy.calculateManagementPerformance(
                new SimulationParam(generateMoney.getSalesMoney(), null, null, null,
                        null, null, null, null), performanceConfigMap.get(CodeConstant.ADMINISTRATION));
        Incentive management = buildIncentive(incentiveGenerateBo.getProjectId(), CodeConstant.ADMINISTRATION,
                performanceConfigMap.get(CodeConstant.ADMINISTRATION).getPerformanceConfigId(), null, managementPerformance.getReward());
        // 6.返回结果
        return R.ok().setData(Arrays.asList(proBusiness, partBusiness, projectManager, projectTeam, ch, ui, cx, nr, yj, management));
    }

    /**
     * 构建绩效对象
     * @param projectId 项目id
     * @param job2 岗位二类
     * @param performanceConfigId 绩效参数id
     * @param grossReward 毛利奖金
     * @param fixedReward 固定提成
     * @return 绩效实体
     */
    private Incentive buildIncentive(Long projectId, Integer job2, Long performanceConfigId, BigDecimal grossReward, BigDecimal fixedReward) {
        Incentive incentive = new Incentive();
        incentive.setProjectId(projectId);
        incentive.setPerformanceConfigId(performanceConfigId);
        incentive.setJob2(job2);
        incentive.setGrossReward(grossReward);
        incentive.setFixedReward(fixedReward);
        incentive.setTotalReward(CalculateUtil.add(grossReward, fixedReward, 4));
        // 设置二级绩效
        incentive.setChildren(incentiveMapper.getIncentiveAllocation(projectId, job2, performanceConfigId, grossReward, fixedReward));
        return incentive;
    }

    /**
     * 新增绩效版本
     * @param incentiveGenerateBo 绩效生成BO
     * @param userId 用户id
     */
    private void insertIncentiveVersion(IncentiveGenerateBo incentiveGenerateBo, Long userId) {
        IncentiveVersion incentiveVersion = new IncentiveVersion();
        incentiveVersion.setProjectId(incentiveGenerateBo.getProjectId());
        incentiveVersion.setYear(incentiveGenerateBo.getYear());
        incentiveVersion.setVersion(incentiveGenerateBo.getVersion());
        incentiveVersion.setCreator(userId);
        incentiveVersion.setCreateTime(new Date());
        incentiveMapper.insertIncentiveVersion(incentiveVersion);
    }

}